package com.company.utils;

import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

public class ValidateUtil {
    private static Validator validator = null;

    static {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    private ValidateUtil() {
    }

    /**
     * 判断属性是否属于例外属性列表
     *
     * @return true--是例外属性,false--不是例外属性
     */
    private static boolean isExcept(String field, String... exceptFields) {
        if (exceptFields == null)
            return false;

        for (String obj : exceptFields) {
            if (null != obj && obj.length()>0 && field.indexOf(obj) >= 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证对象中的属性的值是否符合注解定义
     *
     * @param obj          需要验证的对象
     * @param exceptFields 不需要验证的属性
     * @return 返回空字符串""表示验证通过,否则返回错误信息,多个字段的错误信息用英文分号[;]分隔
     */
    public static String validate(Object obj, String... exceptFields) {
        if (null == obj) {
            return "被验证对象不能为null";
        }

        String validateMsg = "";
        Set<ConstraintViolation<Object>> validateSet = validator.validate(obj);
        for (ConstraintViolation<Object> constraintViolation : validateSet) {
            String field = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            if (!isExcept(field, exceptFields)) {
//              validateMsg += field + ":" + message + ";";
                validateMsg += message + "!";
            }
        }
        return validateMsg;
    }

    /**
     * 验证对象中的属性的值是否符合注解定义
     *
     * @param obj          需要验证的对象
     * @param exceptFields 不需要验证的属性
     * @return 返回空Map<String, String>(not null)表示验证通过,否则会将各错误字段作为key放入Map,value为错误信息
     */
    public static Map<String, String> validateToMap(Object obj, String... exceptFields) {
        if (null == obj) {
            throw new NullPointerException("被验证对象不能为null");
        }
        Map<String, String> resultMap = Maps.newHashMap();
        Set<ConstraintViolation<Object>> validateSet = validator.validate(obj);
        for (ConstraintViolation<Object> constraintViolation : validateSet) {
            String field = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            if (!isExcept(field, exceptFields)) {
                resultMap.put(field, message);
            }
        }
        return resultMap;
    }
}
